package com.demo.test02;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutionException;

import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;

public class Demo02Test {
	private static TransportClient client;

	private static final String cluster_name = "elasticsearch";
	private static final String hostname = "localhost";
	private static int port = 9300;
	private static final String index = "demo02";
	private static final String type = "person";

	public Demo02Test() throws IOException {
		before();
	}

	/**
	 * 1、创建连接，添加测试数据
	 * 
	 * @throws IOException
	 */
	public void before() throws IOException {
		Settings settings = Settings.settingsBuilder()
				.put("cluster.name", cluster_name) // 设置集群名
				.put("client.transport.ignore_cluster_name", true) // 忽略集群名字验证,
				.build();
		client = TransportClient
				.builder()
				.settings(settings)
				.build()
				.addTransportAddress(
						new InetSocketTransportAddress(new InetSocketAddress(
								hostname, port)));
	}

	public static void main(String[] args) throws InterruptedException,
			ExecutionException, IOException {
		Demo02Test demo = new Demo02Test();
		//demo.deleteIndex();
		demo.initDatas();
		// demo.queryAll();
		// demo.queryByName("天府软件");
		//demo.getAllDatas(7);
		//demo.getAllDatasByPage();
	}

	public void queryByName(String queryString) {
		QueryBuilder nameQueryBuilder = QueryBuilders
				.queryStringQuery(queryString);
		SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
		// SortBuilder sort =
		// SortBuilders.fieldSort("age").order(SortOrder.DESC);
		SearchResponse nameSearchResponse = searchRequestBuilder
				.setQuery(nameQueryBuilder)
				// .addSort(sort) //排序（默认按照score降序）
				.execute().actionGet();

		System.out.println("=======" + queryString + "======");
		int i = 0;
		for (SearchHit shit : nameSearchResponse.getHits()) {
			i++;
			System.out.println(i + "\t" + shit.getScore() + "\t"
					+ shit.getSourceAsString());// shit.getSource
		}
	}

	/**
	 * 
	 * 1、汉字如何匹配？ 2、为啥只有前10条？ 3、如何知道匹配的哪个字段？
	 * 
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public void queryAll() throws InterruptedException, ExecutionException {

		// 查询
		// String queryString = "张";
		// QueryBuilder nameQueryBuilder = QueryBuilders.matchQuery("age", 2);

		// 查询所有
		String queryString = "ALL";
		QueryBuilder nameQueryBuilder = QueryBuilders.matchAllQuery();

		SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
		SortBuilder sort = SortBuilders.fieldSort("age").order(SortOrder.DESC);
		SearchResponse nameSearchResponse = searchRequestBuilder
				.setQuery(nameQueryBuilder).addSort(sort) // 排序（默认按照score降序）
				.execute().actionGet();

		System.out.println("=======" + queryString + "======");
		int i = 0;
		for (SearchHit shit : nameSearchResponse.getHits()) {
			i++;
			System.out.println(i + "\t" + shit.getScore() + "\t"
					+ shit.getSourceAsString());// shit.getSource
		}
	}

	@SuppressWarnings("deprecation")
	public void getAllDatasByPage() {
		long pageNum = 1;
		int pageSize = 7;
		long total = client.prepareCount(index).setTypes(type).execute()
				.actionGet().getCount();
		pageNum = (total / pageSize) + 1;
		
		SortBuilder sort = SortBuilders.fieldSort("no").order(SortOrder.ASC);
		SearchRequestBuilder requestBuilder = client.prepareSearch(index)
				.setTypes(type).setQuery(QueryBuilders.matchAllQuery()).addSort(sort);
		System.out.println("共" + total + "条，每页" + pageSize + "条，共" + pageNum + "页");
		
		for (int i = 1; i <= pageNum; i++) {
			System.out.println("---第" + i + "页数据start---");
			SearchResponse response = requestBuilder.setFrom((i-1)*pageSize)
					.setSize(pageSize).execute().actionGet();
			Iterator<SearchHit> it = response.getHits().iterator();
			int k = 1;
			while (it.hasNext()) {
				System.out.println((k++) + "\t" + it.next().getSourceAsString());
			}
		}
	}

	/**
	 * 使用scroll适合查询前n条数据(n数值较大)
	 * 具体用法再看看？？？？
	 * @param start
	 * @param limit
	 */
	@SuppressWarnings("deprecation")
	public void getAllDatas(int size) {
		SearchResponse scrollResponse = client.prepareSearch(index)
				.setSearchType(SearchType.SCAN).setSize(size)
				.setScroll(TimeValue.timeValueMinutes(1)).execute().actionGet();
		long count = scrollResponse.getHits().getTotalHits();// 第一次不返回数据
		int sum = 0;
		while (sum < count) {
			scrollResponse = client
					.prepareSearchScroll(scrollResponse.getScrollId())
					.setScroll(TimeValue.timeValueMinutes(8)).execute()
					.actionGet();
			SearchHits searchHits = scrollResponse.getHits();
			Iterator<SearchHit> it = searchHits.iterator();
			int k = 1;
			while (it.hasNext()) {
				System.out
						.println((k++) + "\t" + it.next().getSourceAsString());
			}
			sum += searchHits.hits().length;
			System.out.println("总量" + count + " 已经查到" + sum);
		}
	}

	/**
	 * 删除索引
	 */
	public void deleteIndex() {
		DeleteIndexResponse deleteIndexResponse = client.admin().indices()
				.prepareDelete(
						index /*"_all"*/
						).execute().actionGet();
		System.out.println(deleteIndexResponse.getHeaders());
		
	}

	public void initDatas() {
		BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
		String[] addresses = new String[] { "河南省南阳市内乡县XX镇YY号", "四川省成都市天府软件园B" };
		for (int i = 0; i < 200; i++) {
			Map<String, Object> source = new HashMap<>();
			source.put("no", i);
			source.put("name", "张三" + i);
			int age = (int) (new Random().nextDouble() * 100);
			double salary = new Random().nextDouble() * 10000;
			source.put("age", age);
			source.put("salary", salary);
			source.put("address", addresses[i % 2] + i);
			bulkRequestBuilder.add(client.prepareIndex(index, type).setSource(
					source));
		}
		BulkResponse response = bulkRequestBuilder.get();
		System.out.println(response.buildFailureMessage());
	}

}
